var parseResult = new Object();

function tryParseClassFile(classFile) {
	var succeed = "succeed";
	var rtn = succeed;
	var parseCounter;
	
	function convertToBinaryFile() {
		for (var i = 0; i < len; ++i) binaryFile[i] = classFile.charCodeAt(i) & 0xff;
	}
	
	function tryParseMagicAndVersion() {
		if (binaryFile[0] != 0xca || binaryFile[1] != 0xfe || binaryFile[2] != 0xba || binaryFile[3] != 0xbe) {
			rtn = "format error (not start with \"cafebabe\")";
			return;
		}
		parseResult.minor = (binaryFile[4] << 8) + binaryFile[5];
		parseResult.major = (binaryFile[6] << 8) + binaryFile[7];
		if (parseResult.major > 0x33 || (parseResult.major == 0x33 && parseResult.minor > 0)) {
			rtn = "cannot handle this version";
			return;
		}
	}
	
	function tryParseConstant(idx) {				
		function tryCreateUTF8() {
			if (parseCount + 2 >= len) {
				rtn = "format error (too small when parsing UTF8)";
				return;
			}
			this.tag = 1;
			this.length = (binaryFile[parseCount + 1] << 8) + binaryFile[parseCount + 2];
			parseCount += 3;
			if (parseCount + this.length - 1 >= len) {
				rtn = "format error (too small when parsing UTF8)";
				return;
			}
			this.bytes = binaryFile.slice(parseCount, parseCount + this.length);
			parseCount += this.length;
		}
		function tryCreateLong() {
			if (parseCount + 8 >= len) {
				rtn = "format error (too small when parsing Long)";
				return;
			}
			this.tag = 5;
			this.high_bytes = (binaryFile[parseCount + 1] << 8) 
				+ (binaryFile[parseCount + 2] << 8)
				+ (binaryFile[parseCount + 3] << 8)
				+ binaryFile[parseCount + 4];
			this.low_bytes = (binaryFile[parseCount + 5] << 8) 
				+ (binaryFile[parseCount + 6] << 8)
				+ (binaryFile[parseCount + 7] << 8)
				+ binaryFile[parseCount + 8];
			parseCount += 9;
		}
		function tryCreateDouble() {
			if (parseCount + 8 >= len) {
				rtn = "format error (too small when parsing Double)";
				return;
			}
			this.tag = 6;
			this.high_bytes = (binaryFile[parseCount + 1] << 8) 
				+ (binaryFile[parseCount + 2] << 8)
				+ (binaryFile[parseCount + 3] << 8)
				+ binaryFile[parseCount + 4];
			this.low_bytes = (binaryFile[parseCount + 5] << 8) 
				+ (binaryFile[parseCount + 6] << 8)
				+ (binaryFile[parseCount + 7] << 8)
				+ binaryFile[parseCount + 8];
			parseCount += 9;
		}
		function tryCreateClass() {
			if (parseCount + 2 >= len) {
				rtn = "format error (too small when parsing Class)";
				return;
			}
			this.tag = 7;
			this.name_index = (binaryFile[parseCount + 1] << 8) + binaryFile[parseCount + 2];
			parseCount += 3;
		}
		function tryCreateString() {
			if (parseCount + 2 >= len) {
				rtn = "format error (too small when parsing String)";
				return;
			}
			this.tag = 8;
			this.string_index = (binaryFile[parseCount + 1] << 8) + binaryFile[parseCount + 2];
			parseCount += 3;
		}
		function tryCreateF_M_I(theTag) {
			if (parseCount + 4 >= len) {
				rtn = "format error (too small when parsing F_M_I: " + theTag + ")";
				return;
			}
			this.tag = theTag;
			this.class_index = (binaryFile[parseCount + 1] << 8) + binaryFile[parseCount + 2];
			this.name_and_type_index = (binaryFile[parseCount + 3] << 8) + binaryFile[parseCount + 4];
			parseCount += 5;
		}
		function tryCreateNameAndType() {
			if (parseCount + 4 >= len) {
				rtn = "format error (too small when parsing NameAndType)";
				return;
			}
			this.tag = 12;
			this.name_index = (binaryFile[parseCount + 1] << 8) + binaryFile[parseCount + 2];
			this.descriptor_index = (binaryFile[parseCount + 3] << 8) + binaryFile[parseCount + 4];
			parseCount += 5;
		}
	
		if (parseCount >= len) {
			rtn = "format error (too small when parsing constant pool)";
			return;
		}

		switch (binaryFile[parseCount]) {
			case 1: //parse Utf8
				parseResult.constant_pool[idx] = new tryCreateUTF8();
				break;
			case 3: //parse Integer
				//TODO
				break;
			case 4: //parse Float
				//TODO
				break;
			case 5: //parse Long
				parseResult.constant_pool[idx] = new tryCreateLong();
				++idx;
				break;
			case 6: //parse Double
				parseResult.constant_pool[idx] = new tryCreateDouble();
				++idx;
				break;
			case 7: //parse Class
				parseResult.constant_pool[idx] = new tryCreateClass();
				if (rtn != succeed) return;
				break;
			case 8: //parse String
				parseResult.constant_pool[idx] = new tryCreateString();
				if (rtn != succeed) return;
				break;
			case 9: //parse Fieldref
				parseResult.constant_pool[idx] = new tryCreateF_M_I(9);
				if (rtn != succeed) return;
				break;
			case 10: //parse Methodref
				parseResult.constant_pool[idx] = new tryCreateF_M_I(10);
				if (rtn != succeed) return;
				break;
			case 11: //parse InterfaceMethodref
				parseResult.constant_pool[idx] = new tryCreateF_M_I(11);
				if (rtn != succeed) return;
				break;
			case 12: //parse NameAndType
				parseResult.constant_pool[idx] = new tryCreateNameAndType();
				if (rtn != succeed) return;
				break;
			default:
				rtn = "format error (nonexistent constant tag: " + binaryFile[parseCount] + ")";
				return;
				break;
		}
		return idx;
	}
	
	function tryParseConstantPool() {
		function checkConstantPool() {
			//TODO!!
		}
		
		parseResult.constant_pool_count = (binaryFile[8] << 8) + binaryFile[9];
		parseCount = 10;
		parseResult.constant_pool = new Array();
		parseResult.constant_pool[0] = null;
		for (var i = 1; i < parseResult.constant_pool_count; ++i) {
			i = tryParseConstant(i);
			if (rtn != succeed) return;
		}
		checkConstantPool();
	}
	
	function tryParseFlagAndClass() {
		function checkFlagAndClass() {
			//TODO!!
		}
		
		if (parseCount + 5 >= len) {
			rtn = "format error (too small when parsing FlagAndClass)";
			return;
		}
		parseResult.access_flags = (binaryFile[parseCount] << 8) + binaryFile[parseCount + 1];
		parseResult.this_class = (binaryFile[parseCount + 2] << 8) + binaryFile[parseCount + 3];
		parseResult.super_class = (binaryFile[parseCount + 4] << 8) + binaryFile[parseCount + 5];
		parseCount += 6;
		checkFlagAndClass();
	}
	
	function tryParseInterface(idx) {
		//TODO!!
	}
	
	function tryParseInterfaces() {
		function checkInterfaces() {
			//TODO!!
		}
		
		if (parseCount + 1 >= len) {
			rtn = "format error (too small when parsing Interfaces)";
			return;
		}
		parseResult.interfaces_count = (binaryFile[parseCount] << 8) + binaryFile[parseCount + 1];
		parseCount += 2;
		parseResult.interfaces = new Array();
		for (var i = 0; i < parseResult.interfaces_count; ++i) {
			tryParseInterface(i);
			if (rtn != succeed) return;
		}
		checkInterfaces();
	}
	
	function tryCreateField() {
		if (parseCount + 7 >= len) {
			rtn = "format error (too small when parsing Field: " + idx + ")";
			return;
		}
		this.access_flags = (binaryFile[parseCount] << 8) + binaryFile[parseCount + 1];
		this.name_index = (binaryFile[parseCount + 2] << 8) + binaryFile[parseCount + 3];
		this.descriptor_index = (binaryFile[parseCount + 4] << 8) + binaryFile[parseCount + 5];
		this.attributes_count = (binaryFile[parseCount + 6] << 8) + binaryFile[parseCount + 7];
		parseCount += 8;
		this.attributes = new Array();
		for (var i = 0; i < this.attributes_count; ++i) {
			this.attributes[i] = new tryCreateAttribute();
			if (rtn != succeed) return;
		}		
	}
	
	function tryParseFields() {
		function checkFields() {
			//TODO!!
		}
		
		if (parseCount + 1 >= len) {
			rtn = "format error (too small when parsing Fields)";
			return;
		}
		parseResult.fields_count = (binaryFile[parseCount] << 8) + binaryFile[parseCount + 1];
		parseCount += 2;
		parseResult.fields = new Array();
		for (var i = 0; i < parseResult.fields_count; ++i) {
			parseResult.fields[i] = new tryCreateField();
			if (rtn != succeed) return;
			//alert("field " + i + " done");
		}
		checkFields();
	}
	
	function convertToString(bytes) {
		var st = "";
		for (var i = 0; i < bytes.length; ++i) 
			if ((bytes[i] & 128) == 0) {
				st = st + String.fromCharCode(bytes[i]);
			}
			else {
				//TODO!!
				st = st + "0";
			}
		return st;
	}
	
	function tryCreateException() {
		//TODO!!
		
	}
	
	function tryCreateLineNumber() {
		this.start_pc = (binaryFile[parseCount] << 8) + binaryFile[parseCount + 1];
		this.line_number = (binaryFile[parseCount + 2] << 8) + binaryFile[parseCount + 3];
		parseCount += 4;
	}
	
	function tryCreateLocalVariable() {
		this.start_pc = (binaryFile[parseCount] << 8) + binaryFile[parseCount + 1];
		this.length = (binaryFile[parseCount + 2] << 8) + binaryFile[parseCount + 3];
		this.name_index = (binaryFile[parseCount + 4] << 8) + binaryFile[parseCount + 5];
		this.descriptor_index = (binaryFile[parseCount + 6] << 8) + binaryFile[parseCount + 7];
		this.index = (binaryFile[parseCount + 8] << 8) + binaryFile[parseCount + 9];
		parseCount += 10;
	}
	
	function tryCreateAttribute() {
		function getAttributeType(idx) {
			if (idx <= 0 || idx >= parseResult.constant_pool_count) {
				rtn = "format error (attribute index wrong: " + idx + ")";
				return -1;
			}
			if (parseResult.constant_pool[idx].tag != 1) {
				rtn = "format error (constant pool[" + idx + "] is not utf8)";
				return -1;
			}
			var st = convertToString(parseResult.constant_pool[idx].bytes);
			if (st == "SourceFile") {
				return 1;
			}
			else if (st == "ConstantValue") {
				return 2;
			}
			else if (st == "Code") {
				return 3;
			}
			else if (st == "Exceptions") {
				return 4;
			}
			else if (st == "InnerClasses") {
				return 5;
			}
			else if (st == "Synthetic") {
				return 6;
			}
			else if (st == "LineNumberTable") {
				return 7;
			}
			else if (st == "LocalVariableTable") {
				return 8;
			}
			else if (st == "Deprecated") {
				return 9;
			}
			else if (st == "StackMapTable") {
				return 10;
			}
			//alert("no string matches\t" + idx + "\t" + st);
			return -1;
		}
	
		
		if (parseCount + 5 >= len) {
			rtn = "format error (too small when parsing Attribute)";
			return;
		}
		this.attribute_name_index = (binaryFile[parseCount] << 8) + binaryFile[parseCount + 1];
		this.attribute_length = (binaryFile[parseCount + 2] << 24) 
			+ (binaryFile[parseCount + 3] << 16)
			+ (binaryFile[parseCount + 4] << 8) 
			+ binaryFile[parseCount + 5];
		parseCount += 6;
		
		//alert("att_name_idx: " + this.attribute_name_index);
		switch (getAttributeType(this.attribute_name_index)) {
			case 1:
				this.attribute_tag = 1;
				
				if (parseCount + 1 >= len) {
					rtn = "format error (too small when parsing SourceFile)";
					return;
				}
				this.sourcefile_index = (binaryFile[parseCount] << 8) + binaryFile[parseCount + 1];
				parseCount += 2;
				
				break;
			case 2:
				this.attribute_tag = 2;
				
				if (parseCount + 1 >= len) {
					rtn = "format error (too small when parsing ConstantValue)";
					return;
				}
				this.constantvalue_index = (binaryFile[parseCount] << 8) + binaryFile[parseCount + 1];
				parseCount += 2;
				//alert("constantvalue_index: " + this.constantvalue_index);
				
				break;
			case 3:
				this.attribute_tag = 3;
				
				if (parseCount + 11 >= len) {
					rtn = "format error (too small when parsing Code)";
					return;
				}
				this.max_stack = (binaryFile[parseCount] << 8) + binaryFile[parseCount + 1];
				this.max_locals = (binaryFile[parseCount + 2] << 8) + binaryFile[parseCount + 3];
				this.code_length = (binaryFile[parseCount + 4] << 24) 
					+ (binaryFile[parseCount + 5] << 16)
					+ (binaryFile[parseCount + 6] << 8)
					+ binaryFile[parseCount + 7];
				parseCount += 8;
				if (parseCount + this.code_length - 1 >= len) {
					rtn = "format error (too small when parsing Code)";
					return;
				}
				this.code = binaryFile.slice(parseCount, parseCount + this.code_length);
				//TODO
				parseCount += this.code_length;
				this.exception_table_length = (binaryFile[parseCount] << 8) + binaryFile[parseCount + 1];
				parseCount += 2;
				this.exception_table = new Array();
				for (var i = 0; i < this.exception_table_length; ++i) {
					this.exception_table[i] = new tryCreateException();
					if (rtn != succeed) return;
				}
				if (parseCount + 1 >= len) {
					rtn = "format error (too small when parsing Code)";
					return;
				}
				this.attributes_count = (binaryFile[parseCount] << 8) + binaryFile[parseCount + 1];
				parseCount += 2;
				this.attributes = new Array();
				for (var i = 0; i < this.attributes_count; ++i) {
					this.attributes[i] = new tryCreateAttribute();
					if (rtn != succeed) return;
				}
				
				break;
			case 4: //TODO!!
				break;
			case 5: //TODO!!
				break;
			case 6: //TODO!!
				break;
			case 7:
				this.attribute_tag = 7;
				
				if (parseCount + 1 >= len) {
					rtn = "format error (too small when parsing LineNumberTable)";
					return;
				}
				this.line_number_table_length = (binaryFile[parseCount] << 8) + binaryFile[parseCount + 1];
				parseCount += 2;
				this.line_number_table = new Array();
				if (parseCount + (this.line_number_table_length << 2) - 1 >= len) {
					rtn = "format error (too small when parsing LineNumberTable)";
					return;
				}
				for (var i = 0; i < this.line_number_table_length; ++i) {
					this.line_number_table[i] = new tryCreateLineNumber();
					if (rtn != succeed) return;
				}
				
				break;
			case 8:
				this.attribute_tag = 8;
				
				if (parseCount + 1 >= len) {
					rtn = "format error (too small when parsing LocalVariableTable)";
					return;
				}
				this.local_variable_table_length = (binaryFile[parseCount] << 8) + binaryFile[parseCount + 1];
				parseCount += 2;
				this.local_variable_table = new Array();
				if (parseCount + (this.local_variable_table_length * 10) - 1 >= len) {
					rtn = "format error (too small when parsing LocalVariableTable)";
					return;
				}
				for (var i = 0; i < this.local_variable_table_length; ++i) {
					this.local_variable_table[i] = new tryCreateLocalVariable();
					if (rtn != succeed) return;
				}
				
				break;
			case 9: //TODO!!
				break;
			case 10: 
				this.attribute_tag = 10;
				
				//TODO!!
				if (parseCount + this.attribute_length - 1 >= len) {
					rtn = "format error (too small when parsing StackMapTable)";
					return;
				}
				this.s_m_t = binaryFile.slice(parseCount, parseCount + this.attribute_length);;
				parseCount += this.attribute_length;
				//TODO!!
				break;
			default:
				return;
				break;
		}
	}
	
	function tryParseMethods() {
		function tryCreateMethod() {
			
			if (parseCount + 7 >= len) {
				rtn = "format error (too small when parsing Method)";
				return;
			}
			this.access_flags = (binaryFile[parseCount] << 8) + binaryFile[parseCount + 1];
			this.name_index = (binaryFile[parseCount + 2] << 8) + binaryFile[parseCount + 3];
			this.descriptor_index = (binaryFile[parseCount + 4] << 8) + binaryFile[parseCount + 5];
			this.attributes_count = (binaryFile[parseCount + 6] << 8) + binaryFile[parseCount + 7];
			parseCount += 8;
			this.attributes = new Array();
			for (var i = 0; i < this.attributes_count; ++i) {
				this.attributes[i] = new tryCreateAttribute();
				if (rtn != succeed) return;
			}
		}
	
		function checkMethods() {
			//TODO!!
		}
		
		if (parseCount + 1 >= len) {
			rtn = "format error (too small when parsing Methods)";
			return;
		}
		parseResult.methods_count = (binaryFile[parseCount] << 8) + binaryFile[parseCount + 1];
		parseCount += 2;
		parseResult.methods = new Array();
		for (var i = 0; i < parseResult.methods_count; ++i) {
			parseResult.methods[i] = new tryCreateMethod();
			if (rtn != succeed) return;
		}
		checkMethods();
	}
	
	function tryParseAttributes() {
		if (parseCount + 1 >= len) {
			rtn = "format error (too small when parsing Attributes)";
			return;
		}
		parseResult.attributes_count = (binaryFile[parseCount] << 8) + binaryFile[parseCount + 1];
		parseCount += 2;
		parseResult.attributes = new Array();
		for (var i = 0; i < parseResult.attributes_count; ++i) {
			parseResult.attributes[i] = new tryCreateAttribute();
			if (rtn != succeed) return;
		}
	}
	
	function serializeParseResult() {
		function serializeConstant(constant) {
			var cst = "\t";
			switch (constant.tag) {
				case 1:
					cst += "Utf8: (length: " + constant.length + ") (ASCII: " + convertToString(constant.bytes) + ") \r\n";
					break;
				case 3:
					break;
				case 4:
					break;
				case 5:
					cst += "Long: " + constant.high_bytes << 16 + constant.low_bytes + "\r\n";					
					break;
				case 6:
					cst += "Double: (high: " + constant.high_bytes + ") (low: " + constant.low_bytes + ")\r\n";
					break;
				case 7:
					cst += "Class: (name_index: " + constant.name_index + ")\r\n";
					break;
				case 8:
					cst += "String: (string_index: " + constant.string_index + ")\r\n";
					break;
				case 9:
					cst += "Fieldref: (class_index: " + constant.class_index + ") (name_and_type_index: " + constant.name_and_type_index + ")\r\n";
					break;
				case 10:	
					cst += "Methodref: (class_index: " + constant.class_index + ") (name_and_type_index: " + constant.name_and_type_index + ")\r\n";
					break;
				case 11:
					cst += "InterfaceMethodref: (class_index: " + constant.class_index + ") (name_and_type_index: " + constant.name_and_type_index + ")\r\n";
					break;
				case 12:
					cst += "NameAndType: (name_index: " + constant.name_index + ") (descriptor_index: " + constant.descriptor_index + ")\r\n";
					break;
				default:
					//something wrong
					break;
			}
			return cst;
		}
		function serializeInterface() {
			//TODO
		}
		function serializeField(field) {
			var fld = "--Field--\r\n";
			fld += "\taccess_flags: " + field.access_flags + "\r\n";
			fld += "\tname_index: " + field.name_index + "\r\n";
			fld += "\tdescriptor_index: " + field.descriptor_index + "\r\n";
			fld += "\tattributes_count: " + field.attributes_count + "\r\n";
			for (var i = 0; i < field.attributes_count; ++i) {
				fld += "\t--Attribute--\r\n";
				fld += serializeAttribute(field.attributes[i], "\t");
			}
			return fld;
		}
		function serializeMethod(method) {
			var mthd = "--Method--\r\n";
			mthd += "\taccess_flags: " + method.access_flags + "\r\n";
			mthd += "\tname_index: " + method.name_index + "\r\n";
			mthd += "\tdescriptor_index: " + method.descriptor_index + "\r\n";
			mthd += "\tattributes_count: " + method.attributes_count + "\r\n";
			for (var i = 0; i < method.attributes_count; ++i) {
				mthd += "\t--Attribute--\r\n";
				mthd += serializeAttribute(method.attributes[i], "\t");
			}
			return mthd;
		}
		function serializeAttribute(attribute, pfx) {
			var att = "";
			pfx += "\t";
			att += pfx + "attribute_name_index: " + attribute.attribute_name_index + "\r\n";
			att += pfx + "attribute_length: " + attribute.attribute_length + "\r\n";
			switch (attribute.attribute_tag) {
				case 1:
					att += pfx + "(SourceFile)\r\n";
					att += pfx + "sourcefile_index: " + attribute.sourcefile_index + "\r\n";
					break;
				case 2:
					att += pfx + "(ConstantValue)\r\n";
					att += pfx + "constantvalue_index: " + attribute.constantvalue_index + "\r\n";
					break;
				case 3:
					att += pfx + "(Code)\r\n";
					att += pfx + "max_stack: " + attribute.max_stack + "\r\n";
					att += pfx + "max_locals: " + attribute.max_locals + "\r\n";
					att += pfx + "code_length: " + attribute.code_length + "\r\n";
					att += pfx + "code: " + attribute.code + "\r\n";
					att += pfx + "exception_table_length: " + attribute.exception_table_length + "\r\n";
					for (var i = 0; i < attribute.exception_table_length; ++i) {
						att += pfx + "--Exception--\r\n";
						att += pfx + "\tstart_pc: " + attribute.exception_table[i].start_pc + "\r\n";
						att += pfx + "\tend_pc: " + attribute.exception_table[i].end_pc + "\r\n";
						att += pfx + "\thandler_pc: " + attribute.exception_table[i].handler_pc + "\r\n";
						att += pfx + "\tcatch_type: " + attribute.exception_table[i].catch_type + "\r\n";
					}
					att += pfx + "attributes_count: " + attribute.attributes_count + "\r\n";
					for (var i = 0; i < attribute.attributes_count; ++i) {
						att += pfx + "--Attribute--\r\n";
						att += serializeAttribute(attribute.attributes[i], pfx);
					}
					break;
				case 4:
					break;
				case 5:
					break;
				case 6:
					break;
				case 7:
					att += pfx + "(LineNumberTable)\r\n";
					att += pfx + "line_number_table_length: " + attribute.line_number_table_length + "\r\n";
					for (var i = 0; i < attribute.line_number_table_length; ++i) {
						att += pfx + "--LineNumber--\r\n";
						att += pfx + "\tstart_pc: " + attribute.line_number_table[i].start_pc + "\r\n";
						att += pfx + "\tline_number: " + attribute.line_number_table[i].line_number + "\r\n";
					}
					break;
				case 8:
					att += pfx + "(LocalVariableTable)\r\n";
					att += pfx + "local_variable_table_length: " + attribute.local_variable_table_length + "\r\n";
					for (var i = 0; i < attribute.local_variable_table_length; ++i) {
						att += pfx + "--LocalVariable--\r\n";
						att += pfx + "\tstart_pc: " + attribute.local_variable_table[i].start_pc + "\r\n";
						att += pfx + "\tlength: " + attribute.local_variable_table[i].length + "\r\n";
						att += pfx + "\tname_index: " + attribute.local_variable_table[i].name_index + "\r\n";
						att += pfx + "\tdescriptor_index: " + attribute.local_variable_table[i].descriptor_index + "\r\n";
						att += pfx + "\tindex: " + attribute.local_variable_table[i].index + "\r\n";
					}
					break;
				case 9:
					break;
				case 10:
					att += pfx + "(StackMapTable)\r\n";
					att += pfx + "stack_map_table: " + attribute.s_m_t + "\r\n";
					break;
				default:
					//something wrong
					att += "WRONG\r\n";
					break;
			}
			return att;
		}
	
		
		var seri = "";
		seri += "minor: " + parseResult.minor + "\r\n" + "major: " + parseResult.major + "\r\n";
		seri += "constant_pool_count: " + parseResult.constant_pool_count + "\r\n";
		for (var i = 1; i < parseResult.constant_pool_count; ++i) {
			seri += serializeConstant(parseResult.constant_pool[i]);
			if (parseResult.constant_pool[i].tag == 5 
				|| parseResult.constant_pool[i].tag == 6)
				++i;
		}
		seri += "access_flags: " + parseResult.access_flags + "\r\n";
		seri += "this_class: " + parseResult.this_class + "\r\n";
		seri += "super_class: " + parseResult.super_class + "\r\n";
		seri += "interfaces_count: " + parseResult.interfaces_count + "\r\n";
		for (var i = 0; i < parseResult.interfaces_count; ++i)
			seri += serializeInterface(parseResult.interfaces[i]);
		seri += "fields_count: " + parseResult.fields_count + "\r\n";
		for (var i = 0; i < parseResult.fields_count; ++i)
			seri += serializeField(parseResult.fields[i]);
		seri += "methods_count: " + parseResult.methods_count + "\r\n";
		for (var i = 0; i < parseResult.methods_count; ++i)
			seri += serializeMethod(parseResult.methods[i]);
		seri += "attributes_count: " + parseResult.attributes_count + "\r\n";
		for (var i = 0; i < parseResult.attributes_count; ++i)
			seri += serializeAttribute(parseResult.attributes[i], "");
		return seri;
	}

	if (classFile == null || classFile == undefined) return "no class file";
	//check classFile
	var len = classFile.length;
	if (len == undefined) return "class file is not a string";
	if (len == 0) return "class file is empty";
	
	var binaryFile = new Array();
	convertToBinaryFile();
	
	document.getElementById('binary').value = binaryFile;
	
	
	if (len < 24) return "format error (too small)";
	//alert("len >= 24");
	
	tryParseMagicAndVersion();
	if (rtn != succeed) return rtn;
	tryParseConstantPool();
	if (rtn != succeed) return rtn;
	//alert("constant done" + parseResult.constant_pool[52].bytes);
	tryParseFlagAndClass();
	if (rtn != succeed) return rtn;
	tryParseInterfaces();
	if (rtn != succeed) return rtn;
	tryParseFields();
	if (rtn != succeed) return rtn;
	//alert("fields done");
	//alert("field[0].access_flags: " + parseResult.fields[0].access_flags);
	tryParseMethods();
	if (rtn != succeed) return rtn;
	tryParseAttributes();
	if (rtn != succeed) return rtn;
	
	document.getElementById('parse').value = serializeParseResult();
	return succeed;
}